<template>
  <div class="height-100pc">
    <v-card :loading="loading" class="py-2 px-2 height-100pc crud-tree">
      <!--按钮及控件-->
      <v-row no-gutters justify="space-between" align="center">
        <v-col>
          <ButtonRender :buttons="buttons" @buttonClick="doAction" />
        </v-col>
        <!--控件的渲染-->
        <v-col align="end" class="pr-2">
          <template v-if="widgets && widgets.length > 0">
            <div class="col-item" @click="showFilter = !showFilter">
              <v-icon small color="#8091a5">mdi-filter-menu-outline</v-icon>
              过滤
            </div>
            <FilterNavigation
              v-model="showFilter"
              :widgets="widgets"
              :widget-model="queryParam"
              @confirm="load"
            />
          </template>
        </v-col>
      </v-row>
      <v-card-text>
        <v-treeview
          dense
          hoverable
          activatable
          rounded
          :items="items"
          :open.sync="open"
          :load-children="loadChildren"
          :item-key="itemKey"
          @update:active="updateActive"
          :item-text="itemText"
        >
          <template v-slot:label="{ item }">
            <div @dblclick="edit('edit', item)">
              <v-row>
                <v-col> {{ item[itemText] }}</v-col>
                <v-col align="end" class="mr-3">
                  <v-menu
                    v-if="item.id && actions && actions.length > 0"
                    top
                    left
                    offset-y
                    rounded="0"
                    transition="scale-transition"
                    origin="bottom right"
                  >
                    <template v-slot:activator="{ on, attrs }">
                      <v-btn
                        width="0"
                        height="0"
                        tile
                        fab
                        v-bind="attrs"
                        v-on="on"
                      >
                        <v-icon small>mdi-dots-vertical</v-icon>
                      </v-btn>
                    </template>
                    <v-list dense>
                      <v-list-item
                        v-for="(operation, index) in actions"
                        :key="index"
                        @click="doAction(operation.action, item, operation)"
                      >
                        <v-list-item-title>{{
                          operation.text || operation.action
                        }}</v-list-item-title>
                      </v-list-item>
                    </v-list>
                  </v-menu>
                </v-col>
              </v-row>
            </div>
          </template>
          <template v-slot:prepend="{ item }">
            <v-icon
              v-text="
                `mdi-${item.children ? 'home-variant' : 'folder-network'}`
              "
            />
          </template>
        </v-treeview>
      </v-card-text>

      <slot name="add-dialog">
        <FormNavigation
          v-model="actionSwitch.add"
          :dialog-view="dialogView"
          :current-item="currentItem"
          @confirm="edit_"
        />
      </slot>
      <slot name="edit-dialog">
        <FormNavigation
          v-model="actionSwitch.edit"
          :dialog-view="dialogView"
          :current-item="currentItem"
          @confirm="edit_"
        />
      </slot>

      <slot name="delete-dialog">
        <tips-dialog
          v-model="actionSwitch.delete"
          title="确认要删除当前数据项吗?"
          @confirm="delete_(currentItem)"
        />
      </slot>

      <slot name="delete-batch-dialog">
        <tips-dialog
          v-model="actionSwitch.batchDelete"
          title="确认要删除当期所选数据项吗?"
          @confirm="batchDelete_(selected)"
        />
      </slot>

      <slot name="import-dialog">
        <v-dialog v-model="actionSwitch.import" width="400">
          <v-card class="pa-2">
            <v-row no-gutters justify="space-between" align="center">
              <v-col md="6" align="center" class="import-col">
                <v-hover v-slot:default="{ hover }">
                  <div
                    class="import-item-box"
                    :class="{ 'on-hover': hover }"
                    @click="exportTemplate"
                  >
                    <div>
                      <v-icon color="primary" size="100"
                        >mdi-file-download-outline
                      </v-icon>
                    </div>
                    <div class="text">下载模板</div>
                  </div>
                </v-hover>
              </v-col>

              <v-col md="6" align="center" class="import-col">
                <v-hover v-slot:default="{ hover }">
                  <div class="import-item-box" :class="{ 'on-hover': hover }">
                    <div>
                      <file-upload
                        ref="import-upload"
                        :headers="authHeanders"
                        :post-action="apiBase + namespace + '/import'"
                        @input-file="inputFile"
                        @input-filter="inputFilter"
                        class="import-upload"
                        v-model="importFiles"
                      >
                        <v-icon color="primary" size="100"
                          >mdi-file-upload-outline</v-icon
                        >
                      </file-upload>
                    </div>
                    <div class="text" style="margin-top:-8px">上传数据</div>
                  </div>
                </v-hover>
              </v-col>
            </v-row>
            <v-row no-gutters justify="space-between" align="center">
              <v-col md="12">
                <v-progress-linear
                  v-if="importFiles.length"
                  color="light-blue"
                  height="10"
                  :value="importFiles[0].progress"
                  striped
                ></v-progress-linear>
              </v-col>
            </v-row>
          </v-card>
        </v-dialog>
      </slot>
    </v-card>
  </div>
</template>

<script>
  import { TreeService, mixins } from "../api/crud";
  import FormNavigation from "./FormNavigation";
  import TipsDialog from "./TipsDialog";
  // import WidgetButton from "./WidgetButton";
  import ButtonRender from "@/components/ButtonRender";
  import FilterNavigation from "@/components/FilterNavigation";
  import FileUpload from "vue-upload-component";

  export default {
    name: "CrudTree",
    mixins: [mixins],
    components: {
      TipsDialog,
      FormNavigation,
      ButtonRender,
      FilterNavigation,
      FileUpload,
    },
    watch: {
      namespace: "init",
    },
    data: () => ({
      loading: true,
      lazy: false,
      itemText: "",
      items: [],
      open: [],
      showFilter: false,
    }),
    created() {
      this.init();
    },
    methods: {
      init() {
        this.crudService = new TreeService(this.namespace);
        this.dialogView = {};
        this.widgets = [];
        this.buttons = [];
        this.load();
      },
      load() {
        const vm = this;
        vm.loading = true;
        const queryParam = { ...vm.queryParam, ...vm.$route.query };
        vm.crudService.load(queryParam).then((data) => {
          vm.itemKey = data.itemKey;
          vm.itemText = data.itemText;
          vm.lazy = data.lazy;
          vm.open = [];
          const tree = data.tree;
          if (data.editableView) {
            this.dialogView = data.editableView;
          }

          if (tree) {
            vm.handleNodes(
              tree,
              !vm.lazy || Boolean(Object.keys(vm.queryParam).length)
            );

            //是否显示根节点
            if (data.displayRoot) {
              this.items.splice(0, 1, tree);
            } else {
              this.items = [...tree.children];
            }
          } else {
            vm.items = [];
          }

          //初始化控件
          if ((!vm.widgets || vm.widgets.length === 0) && data.widgets) {
            vm.widgets = data.widgets;
          }

          //初始化按钮
          if ((!vm.buttons || vm.buttons.length === 0) && data.buttons) {
            vm.buttons = data.buttons;
          }

          //初始化列事件
          if (
            (!this.actions || this.actions.length === 0) &&
            data.actions &&
            data.actions.length > 0
          ) {
            this.actions = data.actions;
          }

          this.loading = false;
        });
      },
      loadChildren(node) {
        return new Promise((resolve) => {
          this.crudService.loadChildren(node[this.itemKey]).then((children) => {
            if (children) {
              children.forEach((child) => {
                this.handleNodes(child, this.lazy);
              });
            }
            node.children = children;
            resolve(node);
          });
        });
      },
      handleNodes(node, open) {
        if (node.children) {
          node.children.forEach((childNode) => {
            this.handleNodes(childNode, open);
          });

          if (open || !node.parentId) {
            this.open.push(node[this.itemKey]);
          }

          if (node.leaf) {
            delete node.children;
          }
        } else {
          delete node.children;
        }
      },
      updateActive(nodes) {
        this.selected = nodes;
      },
      add(actions) {
        mixins.methods.add.call(this, actions);
        this.currentItem["parentId"] =
          this.selected[0] || (this.items[0] || {})[this.itemKey] || null;
      },
    },
  };
</script>

<style scoped>
 
  .crud-tree >>> .v-treeview-node__root {
    margin-top: 0;
    margin-bottom: 0;
  }

  .col-item,
  .col-item-readonly {
    display: inline-block;
    font-size: 14px;
    color: #8091a5;
    cursor: pointer;
  }

  .col-item:hover,
  .col-item:hover > * {
    color: #3582fb !important;
  }

  .total-count {
    color: #000;
    padding: 0 5px;
  }

  .per-page {
    display: inline-block;
    width: 30px;
    height: 20px;
  }

  .separator {
    border-right: 1px solid #dfe6ee;
    width: 1px;
    height: 18px;
    margin-left: 15px;
    margin-right: 15px;
  }

  .setting-title {
    min-width: 20px;
    font-size: 12px;
    color: #8091a5;
  }

  .setting-content {
    margin-top: 5px;
  }

  .setting-content span {
    font-size: 12px;
    padding: 3px;
    cursor: pointer;
    margin: 0 1px;
    border: 1px solid #ebebeb;
  }

  .setting-content span:hover {
    background: #d7e6fe;
    color: #3582fb;
    border: 1px solid #3582fb !important;
    z-index: 1;
    cursor: pointer;
  }

  .per-current {
    background: #d7e6fe;
    color: #3582fb;
    border: 1px solid #3582fb !important;
    z-index: 1;
    cursor: default;
  }

  .crud-tree >>> .v-progress-linear {
    height: 1px !important;
  }

  .crud-table >>> .v-progress-linear {
    height: 1px !important;
  }

  .import-item-box {
    margin: 10px;
    cursor: pointer;
    background-color: #fafafa;
    transition: opacity 0.4s ease-in-out;
  }

  .import-item-box:not(.on-hover) {
    opacity: 0.6;
  }

  .import-upload >>> label {
    cursor: pointer;
  }

  .import-item-box .text {
    color: #3582fb;
    font-weight: bold;
    padding-bottom: 10px;
  }
</style>
